/******************************************************************************
*
* This file is part of FreeTrack (http://code.google.com/p/qtfreetrack).
* BY Willy Gardiol (willy@gardiol.org)
*
* FreeTrack is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* FreeTrack is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Foobar.  If not, see <http://www.gnu.org/licenses/>
*
******************************************************************************/
#include "layermanager.h"
#include "freetrackwidget.h"
#include "configwidget.h"
#include "tracktable.h"

#include "layerlabel.h"
#include "filenavigator.h"

#include "layertrack.h"
#include "layermap.h"

#include "ftwidgetlist.h"
#include "ftpushbutton.h"

extern ConfigWidget* conf;
extern TrackTable* trackingTable;

LayerManager* layerManager;

int layer_id = 0;
LayerManager::LayerManager(QWidget *parent) :
    FreeTrackWidget( parent )
{
    layerManager = this;

    bindings.clear();
    // Create the LiveTrack by default
    LiveTrack = new LayerTrack(true);

    // Create the scroll widget list and add the LiveTrack
    scroll_area = new FTWidgetList();
    scroll_area->setHelp(
    tr("<center|b>List of Tracks and Maps</center>"\
       "<justify>You can interact with it using your finger. To scroll the list, "\
       "just tap on one item and scroll your finger up or down. The list of items will "\
       "scroll with you.</justify>"\
       "<justify>If you like, you can reorder the layers by holding your finger for half a second "\
       "on one: the screen will become red and a 'delete' icon will appear in the corner. "\
       "Now you can move the layer up and down, a thick red line will show you where the layer will "\
       "be moved to when you lift your finger.</justify>"\
       "<justify>If you want to delete a layer, just drag it over the 'delete' icon, and you will "\
       "be asked to confirm if you really want to delete it.</justify>" ));

    // Create buttons...
    buttonLoadMap = new FTPushButton( QIcon(":/icons/load-map.png"), BUTTON_SIZE);
    buttonLoadMap->setText( tr("map"));
    buttonLoadTrack = new FTPushButton( QIcon(":/icons/load-track.png"), BUTTON_SIZE);
    buttonLoadTrack->setText( tr("track") );
    connect( buttonLoadMap, SIGNAL(clicked()),
                      this, SLOT(loadMap()));
    connect( buttonLoadTrack, SIGNAL(clicked()),
                        this, SLOT(loadTrack()));

    // Connect reorder&delete signals
    connect( scroll_area, SIGNAL(orderChanged(QList<int>)),
                    this, SLOT(reoderLayers(QList<int>)) );
    connect( scroll_area, SIGNAL(itemDeleted(int)),
                    this, SLOT(deleteLayer(int)) );
    // setup the quit handler to save data
    connect( qApp, SIGNAL(aboutToQuit()), this, SLOT(prepareToQuit()));

}

Layer* LayerManager::getLayer(int l)
{
    if ( (l>=0) && (l<layers.count()) )
        return layers.at(l);
    return NULL;
}

LayerTrack* LayerManager::getLivetrack()
{
    return LiveTrack;
}

int LayerManager::countLayers()
{
    return layers.count();
}

int LayerManager::addLayer(Layer *layer)
{
    // Add the layer to the ordered layers list
    layers.append( layer );
    // Add the binding between the layer and its unique id
    bindings.insert( layer_id, layer );
    // add the layer on the scroll area
    scroll_area->appendWidget( layer_id, new LayerLabel( layer ) );
    layer_id++;
    return layer_id;
}

void LayerManager::loadMap()
{
    QString file = FileNavigator::openMap();
    if ( file != "" )
    {
        LayerMap* new_map = new LayerMap(QString("%1: %2").arg(tr("Map"))
                                                          .arg(file),
                                         tr("missing description"));
        if ( new_map->loadMap(file) )
        {
            // add the layer
            addLayer( new_map );
            // I do not like this hack too much, but this seems the less
            // complicating place to link the map redraw signal to FreeTrack update...
            connect( new_map, SIGNAL(redraw()),
                     trackingTable, SLOT(update()) );
        }
        else
            delete new_map;
    }
}

void LayerManager::loadTrack()
{
    QString file = FileNavigator::openTrack( tr("Load track...") );
    if ( file != "" )
    {
        LayerTrack * new_track = new LayerTrack(false);
        if ( new_track->loadTrack(file) )
            addLayer( new_track );
        else
            delete new_track;
    }
}

void LayerManager::reoderLayers(QList<int> list )
{
    QList<Layer*> new_order;

    // Iterate on all layers in list
    foreach (int id, list )
    {
        // Get the layer with the given ID
        Layer* tmp = bindings.value( id, NULL );
        if ( tmp != NULL )
        {   // if such layer exists
            // add it to the new ordered list
            new_order.append( tmp );
            // Try to find it and remove from the old list
            if ( layers.indexOf(tmp) > -1 )
                layers.takeAt( layers.indexOf(tmp) );
        }
    }
    // IF there are some layers left, just add them to the end of the new ordered list
    if ( layers.size() > 0 )
        new_order.append( layers );
    // set the new ordered list as the layer list
    layers = new_order;
}

void LayerManager::deleteLayer(int item_id)
{
    // Get the layer with the given ID
    Layer* tmp = bindings.value( item_id, NULL );
    if ( tmp != NULL )
    {   // if such layer exists, delete it and remove the id/layer binding
        delete layers.takeAt( layers.indexOf( tmp ));
        bindings.take( item_id );
    }
}

void LayerManager::prepareToQuit()
{    
    if ( LiveTrack->isModified() &&
         !( conf->getAutosave() && LiveTrack->isFilenameSet()) )
    {
        if (QMessageBox::question( this,
                                   tr("Save LiveTrack"),
                                   tr("Save current LiveTrack before quit?"),
                                   QMessageBox::Yes|QMessageBox::No,
                                   QMessageBox::NoButton ) != QMessageBox::Yes )
            return;
        LiveTrack->saveTrack(true);
    }
}

QLayout* LayerManager::createHorizontal()
{
    QHBoxLayout* grid = new QHBoxLayout();
    grid->addWidget( scroll_area );
    QVBoxLayout* buttons_grid = new QVBoxLayout();
    buttons_grid->addStretch();
    buttons_grid->addWidget( buttonLoadTrack );
    buttons_grid->addStretch();
    buttons_grid->addWidget( buttonLoadMap );
    buttons_grid->addStretch();
    grid->addLayout( buttons_grid );
    return grid;
}

QLayout* LayerManager::createVertical()
{
    QVBoxLayout* grid = new QVBoxLayout();
    grid->addWidget( scroll_area,2 );
    QHBoxLayout* buttons_grid = new QHBoxLayout();
    buttons_grid->addWidget( buttonLoadTrack );
    buttons_grid->addWidget( buttonLoadMap );
    grid->addLayout( buttons_grid );
    return grid;
}
